# -*- coding: utf-8 -*-
"""
Created on Tue Nov  7 14:27:11 2017
## Written based on keras toolkit
## Model: cnn + dropout
@author: YXL
"""

import keras
from keras.datasets import mnist
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Activation, Dropout
#import numpy as np
from keras import backend as k

img_rows = 28
img_cols = 28
num_classes = 10
#%% Load data
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# keras输入数据有两种格式，一种是通道数放在前面，一种是通道数放在后面，
# 其实就是格式差别而已
if k.image_data_format() == 'channels_first':
    x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
    x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
    input_shape = (1, img_rows, img_cols)
else:
    x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
    x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
    input_shape = (img_rows, img_cols, 1)
# 把数据变成float32更精确
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
# 把类别0-9变成2进制，方便训练
y_train = keras.utils.np_utils.to_categorical(y_train, num_classes)
y_test = keras.utils.np_utils.to_categorical(y_test, num_classes)

#%% Model definition
model = keras.models.Sequential()
#1st layer
model.add(Conv2D(25, (3, 3), input_shape=input_shape))
model.add(MaxPooling2D(2, 2));
#2nd layer
model.add(Conv2D(50, (3, 3)))
model.add(MaxPooling2D(2, 2));
# flatten
model.add(Dropout(0.35))
model.add(Flatten())
#Fully connected layer
model.add(Dense(units = 100))
model.add(Activation('relu'))
model.add(Dropout(0.5))
#Output layer
model.add(Dense(units = 10))
model.add(Activation('softmax'))
#Configuration
model.compile(loss = 'categorical_crossentropy', optimizer = 'adam', metrics = ['accuracy'])
#Find the optimal network parameters
model.fit(x_train, y_train, batch_size = 100, epochs = 2, verbose = 1)

#%% Testing
#case1:
score = model.evaluate(x_test, y_test)
print('Total loss on Testing Set:', score[0])
print('Accuracy of Testing Set:', score[1])
#0.9886, 0.9911
#case2:
result = model.predict(x_test)
from keras.utils import plot_model
plot_model(model, to_file='model.png')